package com.shaw.inappupdate_app.repository

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Environment
import android.util.Log
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.FileProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File
import java.io.InputStream


class Updater(context: Context, scope: CoroutineScope) {
    private val mContext: Context = context
    private var downUrl: String = ""
    private val mscope: CoroutineScope = scope


    private val saveFileName: String = "my.apk"
    private val apkFile: File =
        File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), saveFileName)


    //  get permission
    fun getPerAndDownLoad(url: String) {
        println("url：$url")
        this.downUrl = url
        try {
            downloadApk()
        } catch (ex: Exception) {
            Toast.makeText(mContext, "自动更新异常：${ex.message}", Toast.LENGTH_SHORT)
                .show()
        }
    }


    // get apk from apk service
    private fun downloadApk() {
        mscope.launch(Dispatchers.IO) {
            try {
                performDownload()
                installAPK()
            } catch (e: Exception) {
                e.printStackTrace()
                Log.e("DownloadApk_Error", "下载失败，错误信息：${e.message}")
            }
        }
    }

    // download
    private fun performDownload() {
        val client = OkHttpClient()
        val request = Request.Builder()
            .url(downUrl)
            .build()

        val response = client.newCall(request).execute()

        if (!response.isSuccessful) {
            Log.e("DownloadApk_Error", "下载失败，状态码：${response.code}")
            return
        }

        response.body.contentLength()

        val inputStream: InputStream = response.body.byteStream()
        val fileOutputStream = apkFile.outputStream()

        val buffer = ByteArray(1024)
        var bytesRead: Int
        var totalBytesRead = 0L


        while (true) {
            bytesRead = inputStream.read(buffer)
            if (bytesRead == -1) break

            fileOutputStream.write(buffer, 0, bytesRead)
            totalBytesRead += bytesRead
        }

        fileOutputStream.close()
        inputStream.close()
    }

    // install
    private fun installAPK() {
        try {
            if (!apkFile.exists()) {
                return
            }

            val intent = Intent(Intent.ACTION_VIEW)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            val packageName = mContext.packageName
            val authority = "$packageName.file-provider"
            val apkUri: Uri = FileProvider.getUriForFile(mContext, authority, apkFile)
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
            mContext.startActivity(intent)
            android.os.Process.killProcess(android.os.Process.myPid())
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e("installAPK", e.message.toString())
        }
    }
}